home *** CD-ROM | disk | FTP | other *** search
- /*
- ** CFLOW.C : find module call structure of c program
- ** refer to cflow.doc for how to use
- **
- ** Mark Ellington
- ** 05-27-84
- **
- ** Converted to MS-DOS 2 and C86, adding the following features:
- **
- ** 1. filename wildcard support
- ** 2. -l flag to include line numbers in output
- ** 3. -f flag to include file names in output
- ** 4. #include support (with -h flag, same as C86 V2.20H)
- ** 5. -x flag to generate input for CFLOWX
- ** 6. #define macro() support
- ** 7. -t flag to change to '\t' for indentation
- ** 8. -s flag to allow specification of number of indentation spaces
- ** (default is 4 spaces)
- **
- ** Larry Steeger
- ** 06-12-85
- */
-
- #include <stdio.h> /* C86 header */
-
- #define VOID int
-
- /* external functions */
-
- extern VOID abort();
- extern char *alloc();
- extern VOID exit();
- extern int fclose();
- extern unsigned char *filewdir();
- extern FILE *fopen();
- extern VOID fprintf();
- extern int fputs();
- extern VOID free();
- extern int isalnum();
- extern int isdigit();
- extern int isspace();
- extern char *lower();
- extern char *makefile();
- extern char *makefnam();
- extern char *makepath();
- extern char *realloc();
- extern VOID setmem();
- extern VOID sprintf();
- extern char *strcat();
- extern unsigned char *strchr();
- extern char *strcpy();
- extern unsigned strlen();
- extern int strncmp();
- extern char *strncpy();
- extern int tolower();
-
- #include "cflowx.h" /* CFLOW/CFLOWX header */
-
- #define VERSION 85
- #define RELEASE 06
- #define MODIFIC 20
-
- #define outinfo(S) fputs(S,stdout)
-
- /* display CFLOW logo */
-
- outlogo()
- {
- outinfo("\nCFLOW --> function declarations and calls in C source");
- outinfo("\nby Mark Ellington");
- fprintf(stdout,
- "\n[V%02d.%02d.%02d for C86 by Lawrence R. Steeger]\n",
- VERSION, RELEASE, MODIFIC
- );
- }
-
- /* CFLOW usage help */
-
- outhelp()
- {
- outinfo("\n usage: cflow ");
- outinfo("[-[lft]|[x]] [-hsystem[,project]] ");
- outinfo("[input1[..inputn]] [>output]\n");
- outinfo("\n flags: -hsystem[,project]");
- outinfo("\n #include drive/pathname specification");
- outinfo("\n (usage: C86 V2.20H)");
- outinfo("\n -l include line numbers in output");
- outinfo("\n -f include file names in output");
- outinfo("\n -sn number of indentation spaces");
- outinfo("\n -t tabs rather than spaces for indentation");
- outinfo("\n -x generate input for CFLOWX\n");
- outinfo("\ndefaults: cflow -s4 [input] >stdout");
- }
-
- typedef struct _cflow { /* recursive execution structure */
-
- struct _cflow *_chain; /* previous CFLOW structure */
-
- int _fnmbr, /* current file name index */
- _level, /* level of open "{"s or #includes */
- _prevchar, /* previous character in input buffer */
- _curchar, /* current character in input buffer
- ** array subscript
- */
- _curline, /* current line in input dataset */
- _define, /* #define flag */
- _defdcl; /* name declaration offset */
-
- unsigned char _delimit, /* #include file name delimiter */
- *_defname,/* defined name buffer */
- *_name, /* module name buffer */
- *_ins, /* source input line buffer */
- *_fname, /* source file name buffer */
- *_fpname; /* source file/pathname buffer */
-
- FILE *_fptr; /* input file pointer */
-
- } CFLOW;
-
- /* useability macros for CFLOW structure elements */
-
- #define chain cflowp->_chain
- #define fnmbr cflowp->_fnmbr
- #define level cflowp->_level
- #define prevchar cflowp->_prevchar
- #define curchar cflowp->_curchar
- #define curline cflowp->_curline
- #define define cflowp->_define
- #define defdcl cflowp->_defdcl
- #define delimit cflowp->_delimit
- #define defname cflowp->_defname
- #define name cflowp->_name
- #define ins cflowp->_ins
- #define fname cflowp->_fname
- #define fpname cflowp->_fpname
- #define fptr cflowp->_fptr
-
- /* runtime flags */
-
- static int hflag = FALSE, /* -h #include drive/pathname */
- lflag = FALSE, /* -l show line numbers */
- fflag = FALSE, /* -f show file names */
- sflag = FALSE, /* -s space indentation count */
- tflag = FALSE, /* -t tab indentation flag */
- xflag = FALSE; /* -x generate CFLOWX input */
-
- static int fnumber = 0, /* C source file counter */
- flevel = 0, /* C source file level */
- mnumber = 0; /* C source file main counter */
-
- static unsigned char *filepath = NULL, /* default file/path name */
- *hsystem = NULL, /* -hsystem specification */
- *hproject = NULL, /* -h,project specification */
- *tab = " "; /* -t indentation */
-
- static unsigned char newLine[] = {"\n"};
-
- static CFLOW *cflowp = NULL; /* current CFLOW execution ptr */
-
- /* mainline */
-
- main(argc,argv)
- int argc;
- unsigned char * argv[];
- {
- unsigned char *fp,
- *pp; /* temporary file/path pointer */
-
- int fcount, /* C source file counter */
- i,
- j;
-
- if (argc < 2) { /* display CFLOW help */
-
- outlogo();
- outhelp();
- exit(1);
- }
-
- cflowp = alloc(sizeof(CFLOW)); /* 1st execution structure */
-
- name = alloc(MAXBUF); /* module name buffer */
- ins = alloc(MAXBUF); /* input line buffer */
- fname = alloc(MAXPATH); /* current file name */
- fpname = alloc(MAXPATH); /* current file/path name */
-
- filepath = alloc(1); /* dummy file/path name */
- *filepath = EOS;
-
- for (i=1; i < argc; i++) { /* process all flags */
- if (*argv[i] == '-') {
- flags(argv[i]);
- for (j = i--, --argc; j < argc; j++)
- argv[j] = argv[j+1];
- }
- }
-
- if (!xflag) outlogo(); /* display CFLOW logo */
-
- if (hsystem != NULL) /* display -h system prefix */
- if (*hsystem)
- output(HDRSYST, hsystem);
-
- if (hproject != NULL) /* display -h project prefix */
- if (*hproject)
- output(HDRPROJ, hproject);
-
- for (i=1; i < argc; i++) { /* process all files */
- if (*argv[i]) {
- fnmbr = mnumber++;
- strcpy(fname, argv[i]); /* get file name */
- lower(fname);
-
- free(filepath); /* get file/path name */
- filepath = makepath(fname);
-
- if ((strchr(fname, '*') != NULL) /* wildcards */
- || (strchr(fname, '?') != NULL)) {
-
- /* process all matching file names */
-
- fcount = 0;
- while ((fp = filewdir(argv[i],0x00)) != NULL) {
-
- if (!fcount) {
- pp = makepath(fname);
- output(WILDPTH, pp);
- free(pp);
- pp = makefile(fname);
- output(WILDNME, pp);
- free(pp);
- }
-
- ++fcount;
- lower(fp);
- strcpy(fname,fp);
- makefnam(fp, filepath, fpname);
- flevel = level = 0;
- modules();
- free(fp);
- }
-
- if (!fcount) output(WILDNF, fname);
- }
- else { /* no wildcards */
- strcpy(fpname, fname);
- strcpy(fname, (pp=makefile(fname)));
- free(pp);
- flevel = level = 0;
- modules();
- }
- }
- }
- exit(0);
- }
-
- /* process command line flags */
-
- int flags(flag)
- unsigned char *flag;
- {
- unsigned char *hp;
-
- int i;
-
- for (i=1; i < strlen(flag); i++)
- switch (tolower(flag[i])) {
-
- case 'h': /* -h header specifications */
- hflag = TRUE;
- i++;
-
- if (hsystem != NULL)
- free(hsystem);
- if ((hp = strchr(&flag[i], ',')) != NULL)
- *hp++ = EOS;
- hsystem = alloc((strlen(&flag[i]) + 1));
- strcpy(hsystem, lower(&flag[i]));
-
- if (hp) {
- if (hproject != NULL)
- free(hproject);
- hproject = alloc((strlen(hp) + 1));
- strcpy(hproject, lower(hp));
- }
-
- i=strlen(flag); /* force break in for loop */
- break;
-
- case 'l': /* -l include line numbers */
- lflag = TRUE;
- break;
-
- case 'f': /* -f include file names */
- fflag = TRUE;
- break;
-
- case 's': /* -s spaces for indentation */
- if (tflag) {
- fprintf(stdout,
- "\n-s is mutually exclusive with -t");
- outhelp();
- exit(1);
- }
- if (!isdigit(flag[i+1])) { /* -s only ! */
-
- /* note: -s implies default */
-
- sflag = strlen(tab);
- break;
- }
- sflag = 0;
- while (isdigit(flag[++i]))
- sflag = (sflag * 10) + ((int)flag[i] - '0');
- --i;
-
- if (sflag) {
- tab = alloc(sflag + 1);
- setmem(tab, sflag, ' ');
- break;
- }
-
- /* note: -s0 implies -t */
-
- case 't': /* -t tabs for indentation */
- if (sflag) {
- fprintf(stdout,
- "\n-t is mutually exclusive with -s");
- outhelp();
- exit(1);
- }
- tflag = TRUE;
- tab = "\t";
- break;
-
- case 'x': /* -x generate CFLOWX file */
- xflag = TRUE;
- break;
-
- default:
- fprintf(stdout, "\nUnknown flag: \"%c\"", flag[i]);
- outhelp();
- exit(1);
- }
- flag[0] = EOS; /* clear flag */
- }
-
- /* find function declarations and calls */
-
- modules()
- {
- int breakc, /* comment/quotes break character */
- decl, /* module declaration line flag */
- header, /* in function header (before 1st '{') */
- j, /* loop index */
- lastlin, /* last line of file flag */
- modname(); /* module name extractor */
-
- unsigned char c, /* current input character */
- *pp; /* temporary path name pointer */
-
- fnmbr = fnumber++; /* set & increment C source file number */
-
- /* the following switch() provides -h flag support
- ** as documented for the C86 V2.20H -h flag.
- */
-
- switch (delimit) { /* #include/command line file opens */
-
- case '"': /* #include "filename" */
- if (*filepath) {
- fpname =
- alloc((strlen(filepath) + strlen(fname) + 1));
- strcpy(fpname, filepath);
- strcat(fpname, fname);
- }
- else {
- fpname = alloc((strlen(fname) + 1));
- strcpy(fpname, fname);
- }
- if ((fptr = fopen(fpname, "r+")) != NULL) break;
- free(fpname);
-
- case '>': /* #include <filename> */
- if (hproject != NULL) {
- if (*hproject) {
- fpname =
- alloc((strlen(hproject) + strlen(fname) + 1));
- strcpy(fpname, hproject);
- strcat(fpname, fname);
- if ((fptr=fopen(fpname,"r+")) != NULL) break;
- free(fpname);
- }
- }
-
- if (hsystem != NULL) {
- if (*hsystem) {
- fpname =
- alloc((strlen(hsystem) + strlen(fname) + 1));
- strcpy(fpname, hsystem);
- strcat(fpname, fname);
- if ((fptr=fopen(fpname,"r+")) != NULL) break;
- free(fpname);
- }
- }
-
- if (hflag || delimit != '"') {
- output(FILEERR, fname);
- return;
- }
-
- /* #include "filename" without -h */
-
- fpname = alloc((strlen(fname) + 1));
- strcpy(fpname, fname);
-
- default: /* command line filename */
- if ((fptr = fopen(fpname, "r+")) == NULL) {
- output(FILEERR, fpname);
- return;
- }
- break;
- }
-
- /* initialize flags/tokens */
-
- breakc = prevchar = lastlin = header = FALSE;
-
- curline = 0; /* 1st character in buffer */
-
- /* identify C source/#include file name */
-
- pp = makepath(fpname); /* get path name */
-
- output(FILEPTH, pp); /* show C source path name */
- output(FILENME, fname); /* show C source file name */
-
- free(pp); /* free path name */
-
- do {
- if (lastlin = fgets()) /* read a line of source */
- ++curline;
-
- define = decl = FALSE; /* assume nothing */
- curchar = 0; /* start of line */
- defname = NULL; /* clear defined name pointer */
-
- if (prevchar != '\\') /* reset previous if not \ */
- prevchar = FALSE;
-
- while (ins[curchar]) { /* process all characters */
-
- if (breakc) { /* comment/quote in progress */
- if (skipold(&breakc))
- break;
- }
-
- switch (ins[curchar]) {
-
- case '\"': /* start quoted string */
- case '\'': /* start quoted constant */
- case '/' : /* start comment ? */
- skipnew(&breakc);
- break;
-
- case '#': /* pre-processor tokens */
- if (includes()) /* #include */
- break;
- if (defines()) /* #define */
- break;
- goto notsupp; /* unsupported */
-
- case '{': /* compound statement start */
- level++;
- header = FALSE;
- break;
-
- case '}': /* compound statement end */
- level--;
- if (level < 0) { /* nest error */
- output(NESTERR, fpname);
- level = 0;
- }
- break;
-
- case '(': /* function/macro call/declare */
-
- if (define) { /* #define macro() */
- if (!lookmac(curchar))
- goto notfunc;
- macname(); /* macro name */
- break;
- }
-
- if (!lookmod(curchar)) /* module name */
- goto notfunc;
- j = modname();
-
- if (!j) goto notfunc; /* not function */
-
- decl = TRUE; /* function */
-
- if (j == 2) /* declaration */
- header = TRUE;
-
- break;
-
- notsupp:
- notfunc:
- default: /* all other characters */
- break;
- }
-
- if (ins[curchar]) prevchar = (int)ins[curchar++];
- }
-
- if (header && !decl && !breakc && !define) {
-
- /* function declaration argument declarations */
-
- comout(ins);
- if (ins[0]) output(FUNCARG, ins);
- }
-
- if (defname != NULL) free(defname);
-
- } while (lastlin); /* = FALSE if last line */
-
- fclose(fptr);
-
- if (!delimit) output(NOFUNC, newLine);
-
- return;
- }
-
- /* process in progress comments and quoted character or strings */
-
- int skipold(breakc)
- int *breakc;
- {
- while (ins[curchar] && *breakc) { /* !EOS & break in progress */
-
- switch (ins[curchar]) {
-
- case '\\': /* escape sequence */
- if (ins[(curchar+1)])
- ++curchar; /* skip a character */
- break;
-
- case '\'': /* end quoted character */
- if (*breakc != '\'') goto notbreak;
- *breakc = FALSE;
- break;
-
- case '"': /* end quoted string */
- if (*breakc != '"') goto notbreak;
- *breakc = FALSE;
- break;
-
- case '*': /* end comment ? */
- if (*breakc != '/') goto notbreak;
- if (ins[(curchar+1)] == '/') {
- ++curchar;
- *breakc = FALSE;
- break;
- }
-
- notbreak:
- default: /* other characters */
- break;
- }
-
- if (ins[curchar]) prevchar = (int)ins[curchar++];
- }
-
- return (*breakc);
- }
-
- /* start new comment or quoted character/string process */
-
- int skipnew(breakc)
- int *breakc;
- {
- switch (ins[curchar]) { /* not EOS */
-
- case '/': /* start comment ? */
- if (ins[++curchar] != '*') {
- break;
- }
-
- *breakc = '/'; /* comment started */
-
- if (ins[curchar]) prevchar = (int)ins[curchar];
- break;
-
- case '\'': /* start quoted constant */
- case '"': /* start quoted string */
- *breakc = (int)ins[curchar];
- break;
-
- default: /* unknown ? */
- break;
- }
-
- return (*breakc);
- }
-
- /* process #include */
-
- includes()
- {
- unsigned char delim, *fp;
- int filecur, fnamel;
- CFLOW *cflows;
-
- filecur = curchar;
-
- if (strncmp("#include", &ins[filecur], 8) != 0)
- return (FALSE); /* not #include */
-
- for (filecur += 8; ins[filecur]; filecur++)
- if (!isspace(ins[filecur])) break;
-
- if (!ins[filecur]) return (FALSE); /* #include.. only ?! */
-
- delim = ins[filecur++]; /* file name delimiter */
-
- if (delim != '\"' && delim != '<')
- return (FALSE); /* #include.. what ?! */
-
- if (delim == '<') delim = '>'; /* #include <...> */
-
- if ((fp = strchr(&ins[filecur], delim)) == NULL)
- return (FALSE); /* #include.. what ?! */
-
- if ((fnamel = (fp - &ins[filecur])) == 0)
- return (FALSE); /* #include.. what ?! */
-
- fp = alloc(++fnamel);
- lower(strncpy(fp, &ins[filecur], (fnamel-1)));
-
- filecur += fnamel; /* skip file name + 1 */
-
- cflows = cflowp; /* current CFLOW ptr */
-
- cflowp = alloc(sizeof(CFLOW)); /* allocate new CFLOW */
-
- chain = cflows; /* build new CFLOW */
- name = alloc(MAXBUF);
- ins = alloc(MAXBUF);
- fname = fp;
- if ((strchr(fp, ':') != NULL) /* no -h if drive/path used */
- || (strchr(fp, '\\') != NULL)) {
- delimit = 1; /* include with drive/path */
- fpname = alloc((strlen(fp) + 1));
- strcpy(fpname, fp); /* fpname = fname */
- fname = makefile(fname);
- free(fp);
- }
- else {
- delimit = delim;
- fpname = NULL; /* dynamic fpname at open */
- }
- fnmbr = cflows->_fnmbr + 1;
- flevel++;
- level = 0;
-
- modules(); /* recursive call */
-
- --flevel;
-
- cflows = chain; /* dechain CFLOW structure */
- free(name);
- free(ins);
- free(fname);
- if (fpname != NULL) free(fpname);
- free((char *)cflowp);
-
- cflowp = cflows; /* restore previous CFLOW */
-
- curchar = filecur; /* update buffer index */
- }
-
- /* process #defines */
-
- int defines()
- {
- if (strncmp("define", &ins[(curchar+1)], 6) != 0) {
- define = 0;
- return (FALSE); /* not #define */
- }
-
- define = 1; /* #define 1st level */
- curchar += 6; /* skip #define */
- return (TRUE); /* #define found */
- }
-
- /* look back from position n in string. called with n indicating '('.
- determine macro name.
- */
-
- int lookmac(n)
- int n;
- {
- int i;
-
- i = 0;
-
- if (n) { /* ignore white space */
- --n;
- while (isspace(ins[n])) --n;
- }
-
- if (isalnum(ins[n])) { /* find beginning of macro name */
-
- while (n && isalnum(ins[n-1])) --n;
-
- /* save name
- include definition if macro declaration
- */
-
- if (define < 2) defdcl = n; /* macro name offset */
-
- while (isalnum(ins[n])) /* macro definition */
- name[i++] = ins[n++];
- }
-
- name[i] = EOS;
-
- if (i) {
- comout(name); /* remove any comment from name string */
- if (define < 2) { /* save macro name */
- defname = alloc((strlen(name) + 1));
- strcpy(defname, name);
- }
- return (TRUE); /* macro name found */
- }
- else
- return (FALSE); /* macro name not found */
- }
-
- /* look back from position n in string. called with n indicating '('.
- determine function name.
- */
-
- int lookmod(n)
- int n;
- {
- int i, j, k;
-
- i = 0;
-
- if (n) { /* ignore white space */
- --n;
- while (isspace(ins[n])) --n;
- }
-
- if (isalnum(ins[n])) { /* find beginning of name */
-
- while (n && isalnum(ins[n-1])) --n;
-
- /* save name
- include variable declarations if module declaration
- */
-
- if (level == 0) { /* function declaration */
- defdcl = n;
- j = 0;
- while (ins[j]) /* copy full definition */
- name[i++] = ins[j++];
- defname = alloc((strlen(&ins[defdcl]) + 1));
- j = defdcl;
- k = 0;
- while (isalnum(ins[j])) /* copy name only */
- defname[k++] = ins[j++];
- defname[k] = EOS;
- }
- else /* function call */
- while (isalnum(ins[n]))
- name[i++] = ins[n++];
- }
-
- name[i] = EOS;
-
- if (i) {
- comout(name); /* remove any comment from name string */
- return (TRUE); /* module name found */
- }
- else
- return (FALSE); /* module name not found */
- }
-
- /* terminate string at comment, stripping trailing white space */
-
- comout(s)
- unsigned char *s;
- {
- unsigned char c;
-
- while (c = *s++) {
- if (c == '\n') {
- *--s = EOS;
- break;
- }
- if (c == '/')
- if (*s == '*') {
- *--s = EOS;
- break;
- }
- }
- for (--s; isspace(*s);) *s-- = EOS;
- if (*s == '{') {
- *s = EOS;
- for (--s; isspace(*s);) *s-- = EOS;
- }
- }
-
- /* display macro name */
-
- macname()
- {
- char *cp;
-
- if (define < 2) { /* macro start */
- define++; /* update macro level */
- }
- else {
- output(MACNME, defname); /* macro name */
- cp = alloc((strlen(&ins[defdcl]) + 1));
- strcpy(cp, &ins[defdcl]);
- comout(cp);
- output(MACDCL, cp); /* macro definition */
- output(MACEQU, name); /* macro operand */
- free(cp);
- }
- }
-
- /* display module name with indentation according to { level
-
- returns 0 if not module,
- 1 if call within module,
- 2 if module declaration
- */
-
- modname()
- {
- char *cp;
- int i, result;
-
- if (unreserved() && !external()) { /* builtin/extern entries */
- if (level == 0) {
- output(FUNCNME, defname);/* module name */
- output(FUNCDCL, name); /* module function */
- return (2);
- }
- else {
- output(FUNCREF, name); /* module reference */
- return (1);
- }
- }
- return (0);
- }
-
- /* generate output based upon type of data and execution flags */
-
- output(type, string, operand)
- int type;
- unsigned char *string, *operand;
- {
- char *cptype;
-
- unsigned char outbuf[MAXBUF],
- *filter();
-
- int j, slevel;
-
- slevel = level; /* save current level */
-
- switch (type) { /* generate output strings */
-
- case NOFUNC:
- if (strchr(string, '%') != NULL) {
- sprintf(outbuf, string, operand);
- cptype = outbuf;
- }
- else cptype = string;
- break;
-
- case FUNCREF:
- strcpy(outbuf, tab);
- for (j=0; j < level; ++j)
- strcat(outbuf, tab);
- sprintf(&outbuf[strlen(outbuf)], "%s()", string);
- cptype = outbuf;
- break;
-
- case FUNCARG:
- cptype = " * %s";
- string = filter(string);
- break;
-
- case FUNCDCL:
- cptype = "** %s";
- string = filter(string);
- break;
-
- case MACEQU:
- cptype = " = %s()";
- string = filter(string);
- break;
-
- case MACDCL:
- cptype = "== %s";
- string = filter(string);
- break;
-
- case FILENME:
- if (flevel) {
- cptype = " C Include: %s";
- level = flevel;
- }
- else cptype = " C Source: %s";
- break;
-
- case FILEPTH:
- if (*string)
- if (flevel) {
- cptype = "C Include Drive/Path: %s";
- level = flevel;
- }
- else cptype = " C Source Drive/Path: %s";
- else cptype = "";
- break;
-
- case HDRSYST:
- cptype = " C System Header: %s";
- break;
-
- case HDRPROJ:
- cptype = " C Project Header: %s";
- break;
-
- case WILDPTH:
- if (*string)
- cptype = " WildCard Drive/Path: %s";
- else cptype = "";
- break;
-
- case WILDNME:
- cptype = " WildCard Files: %s";
- break;
-
- case WILDNF:
- cptype = " No Files Matching: %s";
- break;
-
- case FILEERR:
- if (flevel)
- cptype = "Can't Open C Include: %s";
- else cptype = " Can't Open C Source: %s";
- break;
-
- case NESTERR:
- cptype = " {..} Nesting Error: %s";
- break;
-
- case MACNME:
- case FUNCNME:
- break;
-
- default:
- fprintf(stderr,
- "\noutput(%d): internal error\n", type);
- exit(1);
- }
-
- if (!xflag) {
- switch (type) { /* perform spacing for types */
-
- case FUNCDCL: /* function declaration */
- case MACDCL: /* macro declaration */
- case WILDPTH: /* wildcard path name */
- case FILEPTH: /* file pathname */
- fputs(newLine, stdout);
- if (!*cptype) break;
-
- case WILDNME: /* wildcard specification */
- case FILENME: /* C source file name */
- case FUNCARG: /* function argument */
- case FUNCREF: /* function reference */
- case MACEQU: /* macro equate */
- case NESTERR: /* nesting error */
- case FILEERR: /* file error */
- case HDRSYST: /* -h system prefix */
- case HDRPROJ: /* -h project prefix */
- case WILDNF: /* no files match wildcard */
- fputs(newLine, stdout);
- break;
-
- case MACNME: /* macro name */
- case FUNCNME: /* function name */
- return;
-
- case NOFUNC: /* non-function output */
- default:
- break;
- }
-
- if (*cptype) {
- outhdr(type); /* generate line header */
- fprintf(stdout, cptype, string); /* output line */
- }
- }
- else { /* generate CFLOWX output */
- if (type) {
- if (type == FILEERR) {
- output(FILEPTH, "", "");
- strcpy(outbuf, "* ");
- strcat(outbuf, string);
- output(FILENME, outbuf, "");
- level = slevel;
- return;
- }
-
- if (type == WILDNF) {
- output(WILDPTH, "", "");
- strcpy(outbuf, "# ");
- strcat(outbuf, string);
- output(WILDNME, outbuf, "");
- level = slevel;
- return;
- }
-
- fprintf(stdout,
- cxref(MAXFLDS),
- type,
- fnmbr,
- level,
- curline,
- string
- );
- }
- }
-
- level = slevel; /* restore current level */
- }
-
- /* output line heading */
-
- outhdr(type)
- int type;
- {
- if (type && curline) {
- if (fflag) fprintf(stdout, "%s ", fpname);
- if (lflag) fprintf(stdout, "%5d: ", curline);
- }
- }
-
- /* C string filter for extraneous white space */
-
- unsigned char *filter(string)
- unsigned char *string;
- {
- int j;
-
- while (isspace(*string)) ++string;
-
- for (j=0; string[j]; j++)
- if (isspace(string[j])) string[j] = ' ';
-
- for (j=0; string[j] && string[(j+1)] != EOS; j++) {
- if (string[j] == ' ' && string[(j+1)] == ' ') {
- strcpy(&string[j], &string[(j+1)]);
- continue;
- }
- if (string[j] == ' ' && string[(j+1)] == '(') {
- strcpy(&string[j], &string[(j+1)]);
- continue;
- }
- if (string[j] == ',' && string[(j+1)] == ' ') {
- strcpy(&string[(j+1)], &string[(j+2)]);
- continue;
- }
- if (string[j] == '*' && string[(j+1)] == ' ')
- strcpy(&string[(j+1)], &string[(j+2)]);
- }
-
- return (string);
- }
-
- /* test for C reserved words */
-
- unreserved()
- {
- if (strncmp(name, "return", 6) == 0
- && !iscname(name[6])) return (FALSE);
- else if (strncmp(name, "if", 2) == 0
- && !iscname(name[2])) return (FALSE);
- else if (strncmp(name, "while", 5) == 0
- && !iscname(name[5])) return (FALSE);
- else if (strncmp(name, "for", 3) == 0
- && !iscname(name[3])) return (FALSE);
- else if (strncmp(name, "switch", 6) == 0
- && !iscname(name[6])) return (FALSE);
- else if (strncmp(name, "sizeof", 6) == 0
- && !iscname(name[6])) return (FALSE);
-
- else return (TRUE);
- }
-
- /* detect "extern" function definitions outside of all functions */
-
- external()
- {
- char *cp;
- int i, rc;
-
- if (level) return (FALSE); /* within a function */
-
- for (i=0; ins[i]; i++) if (isalnum(ins[i])) break;
-
- if (ins[i]) {
- if (strncmp(&ins[i], "extern", 6) == 0
- && !iscname(ins[6])) return (TRUE);
- if (strncmp(&ins[i], "typedef", 7) == 0
- && !iscname(ins[7])) return (TRUE);
- }
-
- cp = alloc(strlen(ins));
- strcpy(cp, ins);
- comout(cp);
-
- if (*cp)
- if (cp[(strlen(cp)-1)] != ')') {
- free(cp);
- return (TRUE);
- }
-
- free(cp);
- return (FALSE);
- }
-
- /* read a line of source */
-
- int fgets()
- {
- unsigned char *s;
- int ch, count;
-
- s = ins;
- count = 0;
-
- while ((ch = getc(fptr)) != EOF) {
-
- buflim(count, MAXBUF);
- *s++ = (unsigned char)ch;
- ++count;
-
- if (ch == '\n') {
- buflim(count, MAXBUF);
- *s = EOS;
- return (TRUE); /* not EOF */
- }
- }
-
- buflim(count, MAXBUF);
- *s = EOS;
- return (FALSE); /* EOF */
- }
-
- /* test if buffer limit reached */
-
- int buflim(current, limit)
- int current, limit;
- {
- if (current == limit) {
- fprintf(stderr,
- "\nfgets(): line %d in %s has more than %d characters",
- curline, fpname, MAXBUF);
- exit(1);
- }
- }
-
- /* determine if character is valid in a C name or label */
-
- int iscname(c)
- unsigned char c;
- {
- if (isalnum(c)) return (TRUE); /* a-z and A-Z are valid */
-
- switch (c) { /* plus 4 special characters */
-
- case '_':
- case '@':
- case '$':
- case '#':
- return (TRUE);
- default:
- return (FALSE);
- }
- }
-
- /* end of cflow.c */
-
- e